package com.sunnay.util;

import com.gaby.commons.okhttp.OkHttpConfiguration;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okhttp3.OkHttpClient.Builder;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author lyw
 * @discrption
 * @createTime 2022-04-17 23:24
 */
@Slf4j
@Component
public class OkHttpClientUtils {


    private static final MediaType JSON = MediaType.parse("application/json");
    private static final MediaType XML = MediaType.parse("application/xml; charset=utf-8");
    public static final MediaType FORM_DATA = MediaType.parse("application/x-www-form-urlencoded");

    private OkHttpClient okHttpClient;

    private OkHttpConfiguration okHttpConfiguration;

    private Builder builder;



    public OkHttpClientUtils(){
        this.okHttpConfiguration = new OkHttpConfiguration();
        okHttpClient = new OkHttpClient();
        this.builder = new Builder();
        this.builder.sslSocketFactory(okHttpConfiguration.sslSocketFactory(), okHttpConfiguration.x509TrustManager())
                    .retryOnConnectionFailure(false)
                    .connectionPool(this.okHttpConfiguration.getConnectionPool())
                    .connectTimeout(30, TimeUnit.SECONDS)
                    .readTimeout(30, TimeUnit.SECONDS)
                    .writeTimeout(30,TimeUnit.SECONDS)
                    .hostnameVerifier((hostname, session) -> true);
                    /*.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(SpringContextHolder.getBean(ProxyProperties.class).getProxyServer(), SpringContextHolder.getBean(ProxyProperties.class).getProxyPort())))
                    .proxyAuthenticator((route, response) -> {
                        //设置代理服务器账号密码
                        String credential = Credentials.basic(SpringContextHolder.getBean(ProxyProperties.class).getProxyUser(), SpringContextHolder.getBean(ProxyProperties.class).getProxyPass());
                        return response.request().newBuilder()
                                .header("Proxy-Authorization", credential)
                                .build();
                    }
                    );*/
        this.okHttpClient = this.builder.build();
        //设置最大请求数
        this.okHttpClient.dispatcher().setMaxRequests(1000);
        //设置单机最大请求数据
        this.okHttpClient.dispatcher().setMaxRequestsPerHost(1000);
    }
    /**
     * get 请求
     * @param url  请求url地址
     * @return string
     * */
    public String doGet(String url) {
        return doGet(url, null, null);
    }
    /**
     * get 请求
     * @param url  请求url地址
     * @param params 请求参数 map
     * @return string
     * */
    public String doGet(String url, Map<String, String> params) {
        return doGet(url, params, null);
    }
    /**
     * get 请求
     * @param url  请求url地址
     * @param headers 请求头字段 {k1, v1 k2, v2, ...}
     * @return string
     * */
    public String doGet(String url, String[] headers) {
        return doGet(url, null, headers);
    }
    /**
     * get 请求
     * @param url  请求url地址
     * @param params 请求参数 map
     * @param headers 请求头字段 {k1, v1 k2, v2, ...}
     * @return string
     * */
    public String doGet(String url, Map<String, String> params, String[] headers) {
        StringBuilder sb = new StringBuilder(url);
        if (params != null && params.keySet().size() > 0) {
            boolean firstFlag = true;
            for (String key : params.keySet()) {
                if (firstFlag) {
                    sb.append("?").append(key).append("=").append(params.get(key));
                    firstFlag = false;
                } else {
                    sb.append("&").append(key).append("=").append(params.get(key));
                }
            }
        }
        Request.Builder builder = new Request.Builder();
        if (headers != null && headers.length > 0) {
            if (headers.length % 2 == 0) {
                for (int i = 0; i < headers.length; i = i + 2) {
                    builder.addHeader(headers[i], headers[i + 1]);
                }
            }
        }
        Request request = builder.url(sb.toString()).build();
        return execute(request);
    }
    /**
     * post 请求
     * @param url  请求url地址
     * @param params 请求参数 map
     * @return string
     */
    public String doPostForm(String url, Map<String, String> params) {
        FormBody.Builder builder = new FormBody.Builder();
        if (params != null && params.keySet().size() > 0) {
            for (String key : params.keySet()) {
                builder.add(key, params.get(key));
            }
        }
        Request request = new Request.Builder().url(url).post(builder.build()).build();
        return execute(request);
    }

    public String post(String url, String content, MediaType mediaType, Map<String, String> headers) throws IOException {
        return this.post(url, content, mediaType, headers, false);
    }

    public String post(String url, String content, MediaType mediaType, Map<String, String> headers, boolean async) throws IOException {
        Request request = this.createRequest(url, content, mediaType, headers);
        return this.getResult(request);
    }

    public Request createRequest(String url, String content, MediaType mediaType, Map<String, String> headers) {
        RequestBody requestBody = RequestBody.create(mediaType, content);
        Request.Builder builder = new Request.Builder();
        if (headers != null && headers.size() != 0) {
            Iterator var7 = headers.entrySet().iterator();

            while(var7.hasNext()) {
                Map.Entry<String, String> entry = (Map.Entry)var7.next();
                builder.addHeader((String)entry.getKey(), (String)entry.getValue());
            }
        }

        return builder.url(url).post(requestBody).build();
    }

    public String getResult(Request request) throws IOException {
        Response execute = this.getOkHttpClient().newCall(request).execute();

        String var4;
        try {
            String body;
            if (!execute.isSuccessful()) {
                body = execute.body().string();
                if (body != null) {
                    var4 = body;
                    return var4;
                }

                throw new IOException("Unexpected code" + execute);
            }

            try {
                body = execute.body().string();
                return body;
            } catch (IOException var8) {
                var4 = new String(execute.body().bytes(), "utf-8");
            }
        } finally {
            execute.close();
        }

        return var4;
    }
    /**
     * post 请求, 请求数据为 json 的字符串
     * @param url  请求url地址
     * @param json  请求数据, json 字符串
     * @return string
     */
    public String doPostJson(String url, String json) {
        return exectePost(url, json, JSON);
    }
    /**
     * post 请求, 请求数据为 json 的字符串
     * @param url  请求url地址
     * @param json  请求数据, json 字符串
     * @return string
     */
    public String doPostJson(String url, String json,Map<String,String> headers,MediaType mediaType) {
        return exectePost(url, json, headers,mediaType);
    }
    /**
     * post 请求, 请求数据为 xml 的字符串
     * @param url  请求url地址
     * @param xml  请求数据, xml 字符串
     * @return string
     */
    public String doPostXml(String url, String xml) {
        return exectePost(url, xml, XML);
    }

    private String exectePost(String url, String data,Map<String,String> headers ,MediaType contentType) {
        RequestBody requestBody = RequestBody.create(contentType, data);
        Request.Builder builder = new Request.Builder();
        if (headers != null && headers.size() != 0) {
            Iterator var7 = headers.entrySet().iterator();
            while(var7.hasNext()) {
                Map.Entry<String, String> entry = (Map.Entry)var7.next();
                builder.addHeader((String)entry.getKey(), (String)entry.getValue());
            }
        }
        Request request = builder.url(url).post(requestBody).build();
        return execute(request);
    }
    private String exectePost(String url, String data, MediaType contentType) {
        RequestBody requestBody = RequestBody.create(contentType, data);
        Request request = new Request.Builder().url(url).post(requestBody).build();
        return execute(request);
    }
    private String execute(Request request) {
        Response response = null;
        try {
            response = this.getOkHttpClient().newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return null;
    }

    public OkHttpClient getOkHttpClient(){
        return this.okHttpClient;
    }
}
